package com.wfg.ai.core;

import com.wfg.ai.core.embedding.Embedding;
import com.wfg.ai.core.embedding.EmbeddingVector;
import com.wfg.ai.core.embedding.OpenAIEmbedding;
import com.wfg.ai.core.splitter.AstCodeSplitter;
import com.wfg.ai.core.splitter.CodeChunk;
import com.wfg.ai.core.splitter.LangChainCodeSplitter;
import com.wfg.ai.core.splitter.Splitter;
import com.wfg.ai.core.splitter.SplitterConfig;
import com.wfg.ai.core.splitter.SplitterType;
import com.wfg.ai.core.vectordb.MilvusRestfulVectorDB;
import com.wfg.ai.core.vectordb.MilvusVectorDB;
import com.wfg.ai.core.vectordb.VectorDB;
import com.wfg.ai.core.vectordb.VectorDocument;
import com.wfg.ai.core.vectordb.VectorSearchResult;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * CodeIndexer 是整个库的主入口点
 * 提供对所有功能的访问
 */
public class CodeIndexer {
    /**
     * 创建一个新的 OpenAI 嵌入向量生成器
     * 
     * @param apiKey OpenAI API 密钥
     * @param model 模型名称
     * @return OpenAI 嵌入向量生成器
     */
    public static OpenAIEmbedding createOpenAIEmbedding(String apiKey, String model) {
        OpenAIEmbedding.OpenAIEmbeddingConfig config = new OpenAIEmbedding.OpenAIEmbeddingConfig(apiKey, model);
        return new OpenAIEmbedding(config);
    }

    /**
     * 创建一个新的 OpenAI 嵌入向量生成器（带自定义基础 URL）
     * 
     * @param apiKey OpenAI API 密钥
     * @param model 模型名称
     * @param baseURL 基础 URL
     * @return OpenAI 嵌入向量生成器
     */
    public static OpenAIEmbedding createOpenAIEmbedding(String apiKey, String model, String baseURL) {
        OpenAIEmbedding.OpenAIEmbeddingConfig config = new OpenAIEmbedding.OpenAIEmbeddingConfig(apiKey, model, baseURL);
        return new OpenAIEmbedding(config);
    }

    /**
     * 创建一个新的 Milvus 向量数据库连接
     * 
     * @param host 主机名
     * @param port 端口号
     * @return Milvus 向量数据库连接
     */
    public static MilvusVectorDB createMilvusVectorDB(String host, int port) {
        MilvusVectorDB.MilvusConfig config = new MilvusVectorDB.MilvusConfig(host, port);
        return new MilvusVectorDB(config);
    }

    /**
     * 创建一个新的 Milvus 向量数据库连接（带认证）
     * 
     * @param host 主机名
     * @param port 端口号
     * @param username 用户名
     * @param password 密码
     * @return Milvus 向量数据库连接
     */
    public static MilvusVectorDB createMilvusVectorDB(String host, int port, String username, String password) {
        MilvusVectorDB.MilvusConfig config = new MilvusVectorDB.MilvusConfig(host, port, username, password);
        return new MilvusVectorDB(config);
    }

    /**
     * 创建一个新的 Milvus RESTful 向量数据库连接
     * 
     * @param host 主机名
     * @param port 端口号
     * @return Milvus RESTful 向量数据库连接
     */
    public static MilvusRestfulVectorDB createMilvusRestfulVectorDB(String host, int port) {
        MilvusRestfulVectorDB.MilvusRestfulConfig config = new MilvusRestfulVectorDB.MilvusRestfulConfig(host, port);
        return new MilvusRestfulVectorDB(config);
    }

    /**
     * 创建一个新的 Milvus RESTful 向量数据库连接（带认证）
     * 
     * @param host 主机名
     * @param port 端口号
     * @param username 用户名
     * @param password 密码
     * @return Milvus RESTful 向量数据库连接
     */
    public static MilvusRestfulVectorDB createMilvusRestfulVectorDB(String host, int port, String username, String password) {
        MilvusRestfulVectorDB.MilvusRestfulConfig config = new MilvusRestfulVectorDB.MilvusRestfulConfig(host, port, username, password);
        return new MilvusRestfulVectorDB(config);
    }

    /**
     * 创建一个新的 AST 代码分割器
     * 
     * @param chunkSize 代码块大小
     * @param chunkOverlap 代码块重叠大小
     * @return AST 代码分割器
     */
    public static AstCodeSplitter createAstCodeSplitter(int chunkSize, int chunkOverlap) {
        return new AstCodeSplitter(chunkSize, chunkOverlap);
    }

    /**
     * 创建一个新的 LangChain 代码分割器
     * 
     * @param chunkSize 代码块大小
     * @param chunkOverlap 代码块重叠大小
     * @return LangChain 代码分割器
     */
    public static LangChainCodeSplitter createLangChainCodeSplitter(int chunkSize, int chunkOverlap) {
        return new LangChainCodeSplitter(chunkSize, chunkOverlap);
    }

    /**
     * 创建一个新的代码分割器配置
     * 
     * @param type 分割器类型
     * @param chunkSize 代码块大小
     * @param chunkOverlap 代码块重叠大小
     * @return 代码分割器配置
     */
    public static SplitterConfig createSplitterConfig(SplitterType type, int chunkSize, int chunkOverlap) {
        return new SplitterConfig(type, chunkSize, chunkOverlap);
    }

    /**
     * 创建一个新的代码索引器
     * 
     * @param embedding 嵌入向量生成器
     * @param vectorDB 向量数据库
     * @param collectionName 集合名称
     * @return 代码索引器
     */
    public static Indexer createIndexer(Embedding embedding, VectorDB vectorDB, String collectionName) {
        Indexer.IndexerConfig config = new Indexer.IndexerConfig(embedding, vectorDB, collectionName);
        return new Indexer(config);
    }

    /**
     * 创建一个新的代码索引器（带分割器配置）
     * 
     * @param embedding 嵌入向量生成器
     * @param vectorDB 向量数据库
     * @param collectionName 集合名称
     * @param splitterConfig 分割器配置
     * @return 代码索引器
     */
    public static Indexer createIndexer(Embedding embedding, VectorDB vectorDB, String collectionName, SplitterConfig splitterConfig) {
        Indexer.IndexerConfig config = new Indexer.IndexerConfig(embedding, vectorDB, collectionName, splitterConfig);
        return new Indexer(config);
    }

    /**
     * 创建一个简单的代码索引器（使用 OpenAI 嵌入和 Milvus RESTful 向量数据库）
     * 
     * @param apiKey OpenAI API 密钥
     * @param host Milvus 主机名
     * @param port Milvus 端口号
     * @param collectionName 集合名称
     * @return 代码索引器
     */
    public static Indexer createSimpleIndexer(String apiKey, String host, int port, String collectionName) {
        OpenAIEmbedding embedding = createOpenAIEmbedding(apiKey, "text-embedding-3-small");
        MilvusRestfulVectorDB vectorDB = createMilvusRestfulVectorDB(host, port);
        return createIndexer(embedding, vectorDB, collectionName);
    }

    /**
     * 获取支持的 OpenAI 嵌入模型列表
     * 
     * @return 支持的模型列表
     */
    public static Map<String, Map<String, Object>> getSupportedOpenAIModels() {
        return OpenAIEmbedding.getSupportedModels();
    }

    /**
     * 获取支持的 AST 分割器语言列表
     * 
     * @return 支持的语言列表
     */
    public static List<String> getSupportedAstLanguages() {
        return AstCodeSplitter.getSupportedLanguages();
    }
}